package com.hzw.saas.web.app.hpc.controller;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hzw.saas.api.hpc.IHpcAccountUserService;
import com.hzw.saas.api.hpc.bo.HpcAccountUserBo;
import com.hzw.saas.api.hpc.bo.HpcSharedRecordBO;
import com.hzw.saas.api.hpc.enums.HpcAccountUserType;
import com.hzw.saas.api.hpc.query.SubHpcAccountQuery;
import com.hzw.saas.api.property.IPropertyService;
import com.hzw.saas.api.property.enmus.SysDictKeyEnum;
import com.hzw.saas.api.user.IUserProfileService;
import com.hzw.saas.api.user.bo.CustomerBO;
import com.hzw.saas.api.user.bo.UserProfileBO;
import com.hzw.saas.common.config.annotation.SysLog;
import com.hzw.saas.common.config.util.AssertUtil;
import com.hzw.saas.common.config.util.PageParam;
import com.hzw.saas.common.config.util.PageUtils;
import com.hzw.saas.common.security.utils.SecurityUtils;
import com.hzw.saas.web.app.hpc.dto.CustomerShareDto;
import com.hzw.saas.web.app.hpc.dto.HpcSharedRecordDTO;
import com.hzw.saas.web.app.hpc.param.AllotSubHpcAccountParam;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiOperationSort;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 账号共享
 * @author sonam
 * @sine 2021/9/10 11:02 上午
 */
@RestController
@RequestMapping("/hpc/shared")
@Api(tags = "机时中心/账号共享")
@RequiredArgsConstructor
public class HpcSharedController {
    // 账号最大共享数量
    private final static int MAX_SHARED_COUNT = 50;

    @Resource(name = IPropertyService.SYS_DICT_BEAN)
    private IPropertyService<SysDictKeyEnum> dictService;
    private final IHpcAccountUserService hpcAccountUserService;
    private final IUserProfileService userProfileService;

    @PostMapping("/allot")
    @ApiOperation(value = "用户共享HPC账号", notes = "指定用户ID，共享HPC帐号")
    @ApiOperationSort(1)
    @SysLog(operation = "用户共享HPC账号", mode = 3)
    public ResponseEntity<Void> allotHpcAccountToUser(@Validated @RequestBody AllotSubHpcAccountParam hpcAccountParam) {
        // 检查HpcAccountUserId是否合法
        String hpcAccountUserId = hpcAccountParam.getHpcAccountUserId();
        checkoutHpcAccountUserId(hpcAccountUserId);

        // 获取默认的过期时间
        String propertyValue = dictService.getPropertyValue(SysDictKeyEnum.SHARE_HPC_EXPIRE_TIME, "6");
        int offsetDay;
        try {
            offsetDay = Integer.parseInt(propertyValue);
        } catch (RuntimeException e) {
            offsetDay = 6;
        }

        List<SubHpcAccountQuery> hpcAccountQueries = new ArrayList<>();
        int finalOffsetDay = offsetDay;
        hpcAccountParam.getUserIds().forEach(userId -> {
            SubHpcAccountQuery hpcAccountQuery = new SubHpcAccountQuery();
            hpcAccountQuery.setHpcAccountUserId(hpcAccountUserId);
            hpcAccountQuery.setUserId(userId);
            hpcAccountQuery.setSubHpcAccountStatus(hpcAccountParam.getStatus());
            if (Objects.isNull(hpcAccountParam.getExpireTime())) {
                DateTime expireTime = DateUtil.offset(DateUtil.date(), DateField.MONTH, finalOffsetDay);
                hpcAccountQuery.setExpireTime(expireTime);
            } else {
                hpcAccountQuery.setExpireTime(hpcAccountParam.getExpireTime());
            }
            hpcAccountQueries.add(hpcAccountQuery);
        });
        AssertUtil.assertThrow("账号共享失败，共享数超过上限",hpcAccountUserService.countSub(hpcAccountUserId) + hpcAccountQueries.size() > MAX_SHARED_COUNT);
        hpcAccountUserService.addSubAccountUser(hpcAccountQueries);
        return ResponseEntity.ok().build();
    }


    @PostMapping("/cancel/{hpcAccountUserId}/{userId}")
    @ApiOperation(value = "用户取消共享", notes = "用户取消共享")
    @ApiOperationSort(2)
    @SysLog(operation = "用户取消共享", mode = 3)
    public ResponseEntity<Void> cancelShareHpcAccount(@ApiParam(value = "HPC用户ID") @PathVariable String hpcAccountUserId,@ApiParam(value = "取消共享账号的userId") @PathVariable String userId) {
        // 检查HpcAccountUserId是否合法
        checkoutHpcAccountUserId(hpcAccountUserId);
        hpcAccountUserService.cancelShareHpcAccount(hpcAccountUserId, userId);
        return ResponseEntity.ok().build();
    }

    @GetMapping("/{hpcAccountUserId}/user/list")
    @ApiOperation(value = "用户搜索已共享用户", notes = "用户搜索已共享用户")
    @SysLog(operation = "用户搜索已共享用户")
    @ApiOperationSort(3)
    public ResponseEntity<IPage<CustomerShareDto>> searchShareList(PageParam pageParam,
                                                                   @ApiParam(value = "HPC用户ID") @PathVariable String hpcAccountUserId,
                                                                   @ApiParam(value = "模糊查询字段(客户姓名,客户邮箱,客户手机号码)") @RequestParam(defaultValue = "", required = false) String keyword) {
        IPage<CustomerBO> customerBOIPage = hpcAccountUserService.listShareCustomerByUserId(pageParam, SecurityUtils.getUserId(), hpcAccountUserId, null, keyword);
        return ResponseEntity.ok(PageUtils.convert(customerBOIPage, CustomerShareDto.class));
    }

    @GetMapping("/{hpcAccountUserId}/need/user/list")
    @ApiOperation(value = "用户搜索未共享用户", notes = "用户搜索未共享用户")
    @SysLog(operation = "用户搜索未共享用户")
    @ApiOperationSort(4)
    public ResponseEntity<IPage<CustomerShareDto>> searchNeedShareList(PageParam pageParam,
                                                                       @ApiParam(value = "HPC用户ID") @PathVariable String hpcAccountUserId,
                                                                       @ApiParam(value = "模糊查询字段(客户姓名,客户邮箱,客户手机号码)") @RequestParam(defaultValue = "", required = false) String keyword) {
        if(StrUtil.isBlank(keyword)) return ResponseEntity.ok(new Page<>());
        IPage<CustomerBO> customerBOIPage = hpcAccountUserService.listNeedShareCustomerByUserId(pageParam, SecurityUtils.getUserId(), hpcAccountUserId, null, keyword);
        return ResponseEntity.ok(PageUtils.convert(customerBOIPage, CustomerShareDto.class));
    }

    /**
     * 检查HpcAccountUserId是否合法
     */
    private void checkoutHpcAccountUserId(String hpcAccountUserId) {
        HpcAccountUserBo hpcAccountUserBo = hpcAccountUserService.get(hpcAccountUserId);
        AssertUtil.assertThrow("参数错误，数据为空",  Objects.isNull(hpcAccountUserBo));
        AssertUtil.assertThrow("不能操作，共享账号", hpcAccountUserBo.getIsMain().equals(HpcAccountUserType.SUB.value()));
        AssertUtil.assertThrow("你没有权限操作该HPC用户",  !Objects.equals(hpcAccountUserBo.getUserId(), SecurityUtils.getUser().getUserId()));
    }

    @GetMapping("/record/{hpcAccountUserId}")
    @ApiOperation(value = "查询主账号HPC共享记录", notes = "用户查询主账号HPC共享记录")
    @SysLog(operation = "查询主账号HPC共享记录")
    @ApiOperationSort(5)
    public ResponseEntity<IPage<HpcSharedRecordDTO>> listShardHpcRecord(PageParam pageParam, @PathVariable String hpcAccountUserId) {
        IPage<HpcSharedRecordBO> hpcSharedRecordBOIPage = hpcAccountUserService.listShardHpcRecord(pageParam, hpcAccountUserId);
        List<HpcSharedRecordDTO> HpcSharedRecordDTOs = new ArrayList<>();
        UserProfileBO userProfileBO = userProfileService.get(SecurityUtils.getUserId());
        hpcSharedRecordBOIPage.getRecords().forEach(hpcSharedRecordBO -> {
            HpcSharedRecordDTO hpcSharedRecordDTO = new HpcSharedRecordDTO();
            BeanUtils.copyProperties(hpcSharedRecordBO, hpcSharedRecordDTO);
            // 共享人名称
            hpcSharedRecordDTO.setSharedName(userProfileBO.getRealName());
            // 被共享人名称
            hpcSharedRecordDTO.setBeSharedName(hpcSharedRecordBO.getRealName());
            if(hpcSharedRecordDTO.getIsDelete() == 1) {
                // 取消
                hpcSharedRecordDTO.setInstructions(StrUtil.format("取消共享了算力账号\"{}\"", hpcSharedRecordDTO.getHpcAccount()));
            } else {
                // 分配
                hpcSharedRecordDTO.setInstructions(StrUtil.format("共享了算力账号\"{}\"", hpcSharedRecordDTO.getHpcAccount()));
            }
            HpcSharedRecordDTOs.add(hpcSharedRecordDTO);
        });

        IPage<HpcSharedRecordDTO> hpcSharedRecordDTOIPage = new Page<>(hpcSharedRecordBOIPage.getCurrent(), hpcSharedRecordBOIPage.getSize(), hpcSharedRecordBOIPage.getTotal(), hpcSharedRecordBOIPage.isSearchCount());
        hpcSharedRecordDTOIPage.setRecords(HpcSharedRecordDTOs);
        return ResponseEntity.ok(hpcSharedRecordDTOIPage);
    }

    @GetMapping("/sub/record/{hpcAccountUserId}")
    @ApiOperation(value = "查询副账号HPC共享记录", notes = "用户查询副账号HPC共享记录")
    @SysLog(operation = "查询副账号HPC共享记录")
    @ApiOperationSort(5)
    public ResponseEntity<IPage<HpcSharedRecordDTO>> listSubShardHpcRecord(PageParam pageParam, @PathVariable String hpcAccountUserId) {
        IPage<HpcSharedRecordBO> hpcSharedRecordBOIPage = hpcAccountUserService.listSubShardHpcRecord(pageParam, hpcAccountUserId, SecurityUtils.getUserId());
        // 一定是共享账号
        HpcAccountUserBo hpcAccountUserBo = hpcAccountUserService.get(hpcAccountUserId);
        AssertUtil.assertThrow("参数错误", Objects.isNull(hpcAccountUserBo));
        HpcAccountUserBo mainHpcAccountUserBo = hpcAccountUserService.getMainUserByRecordId(hpcAccountUserBo.getHpcAccountRecordId());
        UserProfileBO userProfileBO = userProfileService.get(mainHpcAccountUserBo.getUserId());
        AssertUtil.assertThrow("参数错误", Objects.isNull(userProfileBO));
        String sharedName = userProfileBO.getRealName();
        List<HpcSharedRecordDTO> HpcSharedRecordDTOs = new ArrayList<>();
        hpcSharedRecordBOIPage.getRecords().forEach(hpcSharedRecordBO -> {
            HpcSharedRecordDTO hpcSharedRecordDTO = new HpcSharedRecordDTO();
            BeanUtils.copyProperties(hpcSharedRecordBO, hpcSharedRecordDTO);
            // 共享人名称
            hpcSharedRecordDTO.setSharedName(sharedName);
            // 被共享人名称
            hpcSharedRecordDTO.setBeSharedName(hpcSharedRecordBO.getRealName());
            if(hpcSharedRecordDTO.getIsDelete() == 1) {
                // 取消
                hpcSharedRecordDTO.setInstructions(StrUtil.format("取消共享了算力账号\"{}\"", hpcSharedRecordDTO.getHpcAccount()));
            } else {
                // 分配
                hpcSharedRecordDTO.setInstructions(StrUtil.format("共享了算力账号\"{}\"", hpcSharedRecordDTO.getHpcAccount()));
            }
            HpcSharedRecordDTOs.add(hpcSharedRecordDTO);
        });

        IPage<HpcSharedRecordDTO> hpcSharedRecordDTOIPage = new Page<>(hpcSharedRecordBOIPage.getCurrent(), hpcSharedRecordBOIPage.getSize(), hpcSharedRecordBOIPage.getTotal(), hpcSharedRecordBOIPage.isSearchCount());
        hpcSharedRecordDTOIPage.setRecords(HpcSharedRecordDTOs);
        return ResponseEntity.ok(hpcSharedRecordDTOIPage);
    }

}
